import crypto from 'crypto';
import { Logger } from '../utils/logger';

export interface TelegramNotificationData {
  orderId: string;
  amount: number;
  userId: number;
  paymentChannel: string;
  status: 'COMPLETED' | 'FAILED' | 'CANCELLED';
  timestamp: Date;
  merchantId: string;
}

export interface CardSellNotificationData {
  orderId: string;
  amount: number;
  userId: number;
  playerUid: string;
  coins: number;
  productId: number | null;
  sellCardSuccess: boolean;
  playerNickname?: string;
  errorMessage?: string;
  timestamp: Date;
  merchantId: string;
}

export class TelegramService {
  private readonly botToken: string;
  private readonly chatId: string; // SaaS系统的接收Chat ID
  private readonly merchantId: string;
  private readonly secretKey: string;
  private readonly baseUrl: string;

  constructor() {
    this.botToken = process.env.TELEGRAM_BOT_TOKEN || '';
    this.chatId = process.env.TELEGRAM_CHAT_ID || '';
    this.merchantId = process.env.TELEGRAM_MERCHANT_ID || '';
    this.secretKey = process.env.TELEGRAM_SECRET_KEY || '';
    this.baseUrl = `https://api.telegram.org/bot${this.botToken}`;

    if (!this.botToken || !this.chatId || !this.merchantId || !this.secretKey) {
      Logger.warn('Telegram服务配置不完整，部分功能可能无法使用', {
        hasBotToken: !!this.botToken,
        hasChatId: !!this.chatId,
        hasMerchantId: !!this.merchantId,
        hasSecretKey: !!this.secretKey
      });
    }
  }

  /**
   * 检查Telegram服务配置是否完整
   */
  isConfigured(): boolean {
    return !!(this.botToken && this.chatId && this.merchantId && this.secretKey);
  }

  /**
   * HTML字符转义
   */
  private escapeHtml(text: string): string {
    return text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
  }

  /**
   * 生成消息签名
   */
  private generateSignature(data: any): string {
    const sortedKeys = Object.keys(data).sort();
    const signString = sortedKeys
      .map(key => `${key}=${data[key]}`)
      .join('&') + `&key=${this.secretKey}`;
    
    return crypto.createHash('md5').update(signString).digest('hex').toUpperCase();
  }

  /**
   * 发送Telegram消息
   */
  private async sendMessage(text: string, parseMode?: 'HTML' | 'Markdown'): Promise<boolean> {
    if (!this.isConfigured()) {
      Logger.warn('Telegram服务未配置，跳过消息发送');
      return false;
    }

    try {
      const url = `${this.baseUrl}/sendMessage`;
      const payload = {
        chat_id: this.chatId,
        text,
        parse_mode: parseMode || 'HTML'
      };

      Logger.info('发送Telegram消息', {
        url,
        chatId: this.chatId,
        textLength: text.length
      });

      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(payload),
      });

      const result = await response.json();

      if (response.ok && result.ok) {
        Logger.info('Telegram消息发送成功', {
          messageId: result.result?.message_id,
          chatId: this.chatId
        });
        return true;
      } else {
        Logger.error('Telegram消息发送失败', new Error(result.description || '未知错误'), {
          errorCode: result.error_code,
          description: result.description,
          chatId: this.chatId
        });
        return false;
      }
    } catch (error) {
      Logger.error('Telegram消息发送异常', error, {
        chatId: this.chatId
      });
      return false;
    }
  }

  /**
   * 发送售卡结果通知到SaaS系统
   */
  async sendCardSellNotification(data: CardSellNotificationData): Promise<boolean> {
    if (!this.isConfigured()) {
      Logger.warn('Telegram服务未配置，跳过售卡通知');
      return false;
    }

    try {
      // 构建通知数据
      const notificationData = {
        merchant_id: this.merchantId,
        order_id: data.orderId,
        amount: data.amount,
        user_id: data.userId,
        player_uid: data.playerUid,
        coins: data.coins,
        product_id: data.productId,
        sell_card_success: data.sellCardSuccess,
        timestamp: Math.floor(data.timestamp.getTime() / 1000)
      };

      // 生成签名
      const signature = this.generateSignature(notificationData);

      // 构建消息内容
      let message: string;

      if (data.sellCardSuccess) {
        // 售卡成功消息
        message = `
🎉 <b>自动充值成功</b>

✅ <b>状态:</b> 自动充值完成
🏪 <b>商户ID:</b> <code>${this.merchantId}</code>
📋 <b>订单号:</b> <code>${data.orderId}</code>
💰 <b>充值金额:</b> ${data.amount} THB
🎮 <b>玩家UID:</b> <code>${data.playerUid}</code>
👤 <b>玩家昵称:</b> ${data.playerNickname || '未知'}
🪙 <b>充值金币:</b> ${data.coins}M
🎯 <b>产品ID:</b> ${data.productId}
⏰ <b>时间:</b> ${data.timestamp.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}
🔐 <b>签名:</b> <code>${signature}</code>

<i>✅ 玩家已自动收到金币，无需手动操作</i>
`;
      } else {
        // 售卡失败消息 - 需要手动操作
        message = `
⚠️ <b>需要手动充值</b>

❌ <b>状态:</b> 自动充值失败，需要手动处理
🏪 <b>商户ID:</b> <code>${this.merchantId}</code>
📋 <b>订单号:</b> <code>${data.orderId}</code>
💰 <b>支付金额:</b> ${data.amount} THB
🎮 <b>玩家UID:</b> <code>${data.playerUid}</code>
👤 <b>玩家昵称:</b> ${data.playerNickname || '查询失败'}
🪙 <b>应充值金币:</b> ${data.coins}M
🎯 <b>产品ID:</b> ${data.productId || '无匹配'}
❌ <b>失败原因:</b> ${this.escapeHtml(data.errorMessage || '未知错误')}
⏰ <b>时间:</b> ${data.timestamp.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}
🔐 <b>签名:</b> <code>${signature}</code>

<b>🚨 请手动给玩家UID: ${data.playerUid} 充值 ${data.coins}M金币</b>
<i>支付已完成，但自动充值失败，请尽快手动处理</i>
`;
      }

      Logger.info('准备发送售卡通知', {
        orderId: data.orderId,
        playerUid: data.playerUid,
        sellCardSuccess: data.sellCardSuccess,
        coins: data.coins,
        productId: data.productId,
        merchantId: this.merchantId,
        signature
      });

      const success = await this.sendMessage(message, 'HTML');

      if (success) {
        Logger.info('售卡通知发送成功', {
          orderId: data.orderId,
          playerUid: data.playerUid,
          sellCardSuccess: data.sellCardSuccess,
          merchantId: this.merchantId
        });
      } else {
        Logger.error('售卡通知发送失败', new Error('Telegram API调用失败'), {
          orderId: data.orderId,
          playerUid: data.playerUid,
          sellCardSuccess: data.sellCardSuccess,
          merchantId: this.merchantId
        });
      }

      return success;
    } catch (error) {
      Logger.error('发送售卡通知异常', error, {
        orderId: data.orderId,
        playerUid: data.playerUid,
        sellCardSuccess: data.sellCardSuccess,
        merchantId: this.merchantId
      });
      return false;
    }
  }

  /**
   * 发送充值成功通知到SaaS系统
   */
  async sendRechargeNotification(data: TelegramNotificationData): Promise<boolean> {
    if (!this.isConfigured()) {
      Logger.warn('Telegram服务未配置，跳过充值通知');
      return false;
    }

    try {
      // 构建通知数据
      const notificationData = {
        merchant_id: this.merchantId,
        order_id: data.orderId,
        amount: data.amount,
        user_id: data.userId,
        payment_channel: data.paymentChannel,
        status: data.status,
        timestamp: Math.floor(data.timestamp.getTime() / 1000)
      };

      // 生成签名
      const signature = this.generateSignature(notificationData);

      // 构建消息内容
      const statusEmoji = data.status === 'COMPLETED' ? '✅' : 
                         data.status === 'FAILED' ? '❌' : '🚫';
      
      const statusText = data.status === 'COMPLETED' ? '充值成功' : 
                        data.status === 'FAILED' ? '充值失败' : '充值取消';

      const message = `
🔔 <b>充值通知</b>

${statusEmoji} <b>状态:</b> ${statusText}
🏪 <b>商户ID:</b> <code>${this.merchantId}</code>
📋 <b>订单号:</b> <code>${data.orderId}</code>
💰 <b>金额:</b> ${data.amount} THB
👤 <b>用户ID:</b> ${data.userId}
💳 <b>支付渠道:</b> ${data.paymentChannel}
⏰ <b>时间:</b> ${data.timestamp.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}
🔐 <b>签名:</b> <code>${signature}</code>

<i>请SaaS系统接收此通知并进行相应处理</i>
`;

      Logger.info('准备发送充值通知', {
        orderId: data.orderId,
        status: data.status,
        amount: data.amount,
        userId: data.userId,
        merchantId: this.merchantId,
        signature
      });

      const success = await this.sendMessage(message, 'HTML');

      if (success) {
        Logger.info('充值通知发送成功', {
          orderId: data.orderId,
          status: data.status,
          merchantId: this.merchantId
        });
      } else {
        Logger.error('充值通知发送失败', new Error('Telegram API调用失败'), {
          orderId: data.orderId,
          status: data.status,
          merchantId: this.merchantId
        });
      }

      return success;
    } catch (error) {
      Logger.error('发送充值通知异常', error, {
        orderId: data.orderId,
        status: data.status,
        merchantId: this.merchantId
      });
      return false;
    }
  }

  /**
   * 发送测试消息
   */
  async sendTestMessage(): Promise<boolean> {
    if (!this.isConfigured()) {
      Logger.warn('Telegram服务未配置，无法发送测试消息');
      return false;
    }

    const testMessage = `
🧪 <b>Telegram Bot 测试消息</b>

✅ 机器人配置正常
🏪 商户ID: <code>${this.merchantId}</code>
⏰ 测试时间: ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}

<i>如果收到此消息，说明Telegram通知功能工作正常！</i>
`;

    Logger.info('发送Telegram测试消息', {
      merchantId: this.merchantId,
      chatId: this.chatId
    });

    return await this.sendMessage(testMessage, 'HTML');
  }

  /**
   * 获取Bot信息（用于测试连接）
   */
  async getBotInfo(): Promise<any> {
    if (!this.botToken) {
      throw new Error('Telegram Bot Token 未配置');
    }

    try {
      const url = `${this.baseUrl}/getMe`;
      const response = await fetch(url);
      const result = await response.json();

      if (response.ok && result.ok) {
        Logger.info('获取Bot信息成功', {
          botId: result.result.id,
          botUsername: result.result.username,
          botFirstName: result.result.first_name
        });
        return result.result;
      } else {
        throw new Error(result.description || '获取Bot信息失败');
      }
    } catch (error) {
      Logger.error('获取Bot信息失败', error);
      throw error;
    }
  }
}

// 创建单例实例
export const telegramService = new TelegramService();

// 检查配置是否完整的工具函数
export function isTelegramConfigured(): boolean {
  return telegramService.isConfigured();
}